package com.iswust.visual.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iswust.visual.mapper.BayonetDataMapper;
import com.iswust.visual.mapper.CityAqiMapper;
import com.iswust.visual.model.CityAqi;
import com.iswust.visual.model.dto.BayonetDayNumDto;
import com.iswust.visual.model.vo.CalenderVo;
import com.iswust.visual.model.vo.DateTimeVo;
import com.iswust.visual.model.vo.WindVo;
import com.iswust.visual.service.CityAqiService;
import com.iswust.visual.utils.WeatherCodeUtil;
import com.iswust.visual.utils.WindDirectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author swust
 * @since 2023-02-17
 */
@Service
public class CityAqiServiceImpl extends ServiceImpl<CityAqiMapper, CityAqi> implements CityAqiService {

    @Autowired
    private CityAqiMapper cityAqiMapper;

    @Autowired
    private BayonetDataMapper bayonetDataMapper;

    @Override
    public List<WindVo> getWindData(DateTimeVo dateTimeVo) {
        final List<WindVo> windDataByDay = cityAqiMapper.getWindDataByDay(dateTimeVo);
        windDataByDay.stream()
                .forEach(windVo -> {
                    windVo.setR(WindDirectionUtil.windDirectionSwitch(Float.valueOf(windVo.getR())));
                });
        return windDataByDay;
    }

    @Override
    public List<CalenderVo> getCalenderData(DateTimeVo dateTimeVo) {
        final List<CityAqi> cityAqiByDate = cityAqiMapper.getCityAqiByDate(dateTimeVo);
        final List<BayonetDayNumDto> bayonetDataByMonth = bayonetDataMapper.getBayonetDataByMonth(dateTimeVo);

        final BayonetDayNumDto bayonetDayNumDtoMin = bayonetDataByMonth.get(0);
        final BayonetDayNumDto bayonetDayNumDtoMax = bayonetDataByMonth.get(bayonetDataByMonth.size() - 1);
        int diff = (bayonetDayNumDtoMax.getTrafficFlow() - bayonetDayNumDtoMin.getTrafficFlow()) / 10;
        for (BayonetDayNumDto bayonetDayNumDto : bayonetDataByMonth) {
            if (10 - ((bayonetDayNumDtoMax.getTrafficFlow() - bayonetDayNumDto.getTrafficFlow()) / diff) == 0) {
                bayonetDayNumDto.
                        setTrafficFlowCode(1);
            } else {
                bayonetDayNumDto.setTrafficFlowCode(10 - ((bayonetDayNumDtoMax.getTrafficFlow() - bayonetDayNumDto.getTrafficFlow()) / diff));
            }
        }

        final Map<Date, BayonetDayNumDto> dateBayonetDayNumDtoMap = bayonetDataByMonth.stream()
                .collect(Collectors.toMap(BayonetDayNumDto::getDate, bayonetDayNumDto -> bayonetDayNumDto));
        Map<Date, CityAqi> dateCityAqiMap = new TreeMap<>();
        for (CityAqi cityAqi : cityAqiByDate) {
            dateCityAqiMap.put(cityAqi.getDate(), cityAqi);
        }

        List<CalenderVo> calenderVoList = new ArrayList<>();
        dateCityAqiMap.forEach((k, v) -> {
            final CalenderVo calenderVo = CalenderVo.builder()
                    .AQI(v.getAqi())
                    .AQILevel(v.getQualityGrade())
                    .temperature(v.getAirTemperature())
                    .water(v.getPercipitation())
                    .windSpeed(v.getWindSpeed())
                    .weatherName(v.getWeatherPhenomenon())
                    .date(k)
                    .build();
            final BayonetDayNumDto bayonetDayNumDto = dateBayonetDayNumDtoMap.get(k);
            calenderVo.setTrafficFlow(bayonetDayNumDto.getTrafficFlow())
                    .setTrafficFlowCode(bayonetDayNumDto.getTrafficFlowCode());
            calenderVoList.add(calenderVo);
        });
        for (CalenderVo calenderVo : calenderVoList) {
            calenderVo.setWeatherCode(WeatherCodeUtil.weatherNameToCode(calenderVo.getWeatherName()));
        }
        return calenderVoList;
    }
}
